

#if defined (ESP8266)
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#endif

#if defined(ESP32)
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#endif

#include <ArduinoJson.h>


const String key = "";//   https://lbs.amap.com/api/webservice/guide/api/weatherinfo/#t1


struct
{
  String weather;
  int temperature;
  String winddirection;
  String windpower;
  String humidity;
} WeatherLive;//实时天气

struct WeatherForcast
{
  String dayweather;         // "dayweather": "雷阵雨",
  String nightweather;     // "nightweather": "多云",
  String daytemp;              // "daytemp": "25",
  String nighttemp;           // "nighttemp": "17",
  String winddirection;
  String windpower;
} ;
WeatherForcast Forcasts_0;//当日预报
WeatherForcast Forcasts_1;//明日预报

//测试HTTPS通讯的网站
const char *host = "restapi.amap.com";
//HTTPS端口443
const int httpsPort = 443;


//高德API获取实时天气
void GetWeatherLive() {

  WiFiClientSecure httpsClient;    //建立WiFiClientSecure对象
  Serial.println(host);
  httpsClient.setInsecure();
  httpsClient.setTimeout(100);
  httpsClient.setBufferSizes(2048, 512); // 语法httpsClient.setBufferSizes(recv, xmit);参数recv：接收缓存大小，该数值大小必须介于512和16384之间（单位字节，类型：int）xmit：发送缓存大小，该数值大小必须介于512和16384之间（单位字节，类型：int）

  Serial.println("HTTPS Connecting"); Serial.println("");
  int r = 0; // 尝试连接服务器并等待
  while ((!httpsClient.connect(host, httpsPort)) && (r < 30)) {
    delay(100);
    Serial.print(".");
    r++;
  }
  // 连接超时后输出"连接失败"信息并返回
  if (r == 30) {
    Serial.println("Connection failed");
    return;
  } else { // 连接成功则输出“连接成功”信息
    Serial.println("Connected...");
  }

  Serial.print("requesting: ");
  Serial.println(host);

  // 建立HTTPS请求信息字符串
  String reqRes = "/v3/weather/weatherInfo?city=" + citycode + "&key=" + key + "&extensions=base";
  String request =  String("GET ") + reqRes + " HTTP/1.1\r\n" +
                    "Host: " + host + "\r\n" +
                    "Connection: close\r\n" +
                    "\r\n";
  // 向服务器发送请求
  httpsClient.print(request);

  Serial.println("request sent");

  // 检查服务器响应信息。一旦查到响应头结束字符，则通过串口监视器
  // 告知用户当前ESP8266已经成功接收服务器响应头信息。
  while (httpsClient.connected()) {
    String line = httpsClient.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }

  // 通过串口监视器输出服务器响应体信息（服务器报文）
  //  Serial.println("==========");
  //  Serial.println("server response payload:");
  String line;
  while (httpsClient.available()) {
    line = httpsClient.readStringUntil('\n');  //Read Line by Line
    //Serial.println(line); //Print response
  }
  //  Serial.println("==========");

  //操作结束，断开服务器连接
  httpsClient.stop();
  Serial.println("closing connection");

  DynamicJsonDocument  jsonBuffer(768);//实时天气768，预报2048,----->>>>>计算：  https://arduinojson.org/v6/assistant/
  DeserializationError error = deserializeJson(jsonBuffer, line);
  if (error)
  {
    Serial.print("天气实况加载json配置失败:");
    Serial.println(error.f_str());
    //return false;
  }
  else {
    Serial.println("天气实况加载json配置成功");
  }
  if (jsonBuffer["status"].isNull() == 0) {//检查到不为空
    if (jsonBuffer["status"] == "1" && jsonBuffer["infocode"] == "10000") {
      JsonObject lives_0 = jsonBuffer["lives"][0];//0表示第一个大括号内容
      //      String weatherlive = jsonBuffer["lives"][0]["weather"];
      //      String temlive = lives_0["temperature"];
      String reporttime = lives_0["reporttime"];
      //      Serial.println(reporttime);
      //reporttime: 2023-06-18 07:02:43
      //      r_year = reporttime.substring(0, 4).toInt();
      //      r_month = reporttime.substring(5, 7).toInt();
      //      r_day = reporttime.substring(8, 10).toInt();
      //      r_hour = reporttime.substring(11, 13).toInt();
      //      Serial.print(r_year); Serial.print(r_month); Serial.println(r_day);

      //数据给结构体，不加as<>会报错
      WeatherLive.weather = lives_0["weather"].as<String>();
      WeatherLive.temperature = lives_0["temperature"].as<int>();
      WeatherLive.winddirection = lives_0["winddirection"].as<String>();
      WeatherLive.windpower = lives_0["windpower"].as<String>();
      WeatherLive.humidity = lives_0["humidity"].as<String>();

    }
  }
}

void GetWeatherForcast() {

  WiFiClientSecure httpsClient;    //建立WiFiClientSecure对象
  Serial.println(host);
  httpsClient.setInsecure();
  httpsClient.setTimeout(100);
  httpsClient.setBufferSizes(2048, 512); // 语法httpsClient.setBufferSizes(recv, xmit);参数recv：接收缓存大小，该数值大小必须介于512和16384之间（单位字节，类型：int）xmit：发送缓存大小，该数值大小必须介于512和16384之间（单位字节，类型：int）
  Serial.println("HTTPS Connecting"); Serial.println("");
  int r = 0; // 尝试连接服务器并等待
  while ((!httpsClient.connect(host, httpsPort)) && (r < 30)) {
    delay(100);
    Serial.print(".");
    r++;
  }
  // 连接超时后输出"连接失败"信息并返回
  if (r == 30) {
    Serial.println("Connection failed");
    return;
  } else { // 连接成功则输出“连接成功”信息
    Serial.println("Connected...");
  }

  Serial.print("requesting: ");
  Serial.println(host);

  // 建立HTTPS请求信息字符串
  String reqRes = "/v3/weather/weatherInfo?city=" + citycode + "&key=" + key + "&extensions=all";
  String request =  String("GET ") + reqRes + " HTTP/1.1\r\n" +
                    "Host: " + host + "\r\n" +
                    "Connection: close\r\n" +
                    "\r\n";
  // 向服务器发送请求
  httpsClient.print(request);

  Serial.println("request sent");

  // 检查服务器响应信息。一旦查到响应头结束字符，则通过串口监视器
  // 告知用户当前ESP8266已经成功接收服务器响应头信息。
  while (httpsClient.connected()) {
    String line = httpsClient.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }

  // 通过串口监视器输出服务器响应体信息（服务器报文）
  //Serial.println("==========");
  //Serial.println("server response payload:");
  String line;
  while (httpsClient.available()) {
    line = httpsClient.readStringUntil('\n');  //Read Line by Line
    //Serial.println(line); //Print response
  }
  //Serial.println("==========");

  //操作结束，断开服务器连接
  httpsClient.stop();
  Serial.println("closing connection");

  DynamicJsonDocument  jsonBuffer(1536);//实时天气768，预报2048,----->>>>>计算：  https://arduinojson.org/v6/assistant/
  DeserializationError error = deserializeJson(jsonBuffer, line);
  if (error)
  {
    Serial.print("天气预报加载json配置失败:");
    Serial.println(error.f_str());
    //return false;
  }
  else {
    Serial.println("天气预报加载json配置成功");
  }
  if (jsonBuffer["status"].isNull() == 0) {//检查到不为空
    if (jsonBuffer["status"] == "1" && jsonBuffer["infocode"] == "10000") {

      //这句不好使
      //      String casts_0_dayweather = jsonBuffer["forcasts"][0]["casts"][0]["dayweather"].as<String>();

      JsonObject forecasts_0 = jsonBuffer["forecasts"][0];
      JsonObject casts_0 = forecasts_0["casts"][0];//当日天气预报
      JsonObject casts_1 = forecasts_0["casts"][1];//当日天气预报

      Forcasts_0.dayweather = casts_0["dayweather"].as<String>();
      Forcasts_0.nightweather = casts_0["nightweather"].as<String>();
      Forcasts_0.daytemp = casts_0["daytemp"].as<String>();
      Forcasts_0.nighttemp = casts_0["nighttemp"].as<String>();

      Forcasts_1.dayweather = casts_1["dayweather"].as<String>();
      Forcasts_1.daytemp = casts_1["daytemp"].as<String>();
      Forcasts_1.nighttemp = casts_1["nighttemp"].as<String>();
      Forcasts_1.winddirection = casts_1["daywind"].as<String>();
      Forcasts_1.windpower = casts_1["daypower"].as<String>();
    }
  }
}



uint8_t WeatherCode(String weather) {
  if (weather == "晴") {
    return 10;
  } else if ( weather == "少云" || weather == "晴间多云") {
    return 11;
  } else if (weather == "多云" || weather == "阴") {
    return 12;
  } else if (weather == "有风" || weather == "平静" || weather == "微风" || weather == "和风" || weather == "清风" || weather == "强风/劲风" || weather == "疾风" || weather == "大风" || weather == "烈风" || weather == "风暴" || weather == "狂爆风" || weather == "飓风" || weather == "热带风暴" || weather == "浮尘" || weather == "扬沙" || weather == "沙尘暴" || weather == "强沙尘暴" || weather == "龙卷风") {
    return 13;
  } else if (weather == "霾" || weather == "中度霾" || weather == "重度霾" || weather == "严重霾" || weather == "雾" || weather == "浓雾" || weather == "强浓雾" || weather == "轻雾" || weather == "大雾" || weather == "特强浓雾") {
    return 14;
  } else if (weather == "阵雨" || weather == "雷阵雨" || weather == "雷阵雨并伴有冰雹" || weather == "强阵雨" || weather == "强雷阵雨" || weather == "极端降雨") {
    return 15;
  } else if (weather == "小雨" || weather == "中雨" || weather == "毛毛雨/细雨" || weather == "雨" || weather == "小雨-中雨" || weather == "雨雪天气" || weather == "雨夹雪" || weather == "阵雨夹雪" || weather == "冻雨") {
    return 16;
  } else if (weather == "大雨" || weather == "暴雨" || weather == "大暴雨" || weather == "特大暴雨" || weather == "中雨-大雨" || weather == "大雨-暴雨" || weather == "暴雨-大暴雨" || weather == "大暴雨-特大暴雨") {
    return 17;
  } else if (weather == "雪" || weather == "阵雪" || weather == "小雪" || weather == "中雪" || weather == "大雪" || weather == "暴雪" || weather == "小雪-中雪" || weather == "中雪-大雪" || weather == "大雪-暴雪") {
    return 18;
  } else if (weather == "热" || weather == "冷" || weather == "未知") {
    return 19;
  } else
    return 0;
}


uint8_t WinddirectionCode(String wind) {
  if (wind == "东") {
    return 21;
  } else if (wind == "东北") {
    return 22;
  } else if (wind == "北") {
    return 23;
  } else if (wind == "西北") {
    return 24;
  } else if (wind == "西") {
    return 25;
  } else if (wind == "西南") {
    return 26;
  } else if (wind == "南") {
    return 27;
  } else if (wind == "东南") {
    return 28;
  } else
    return 0;
}
